package net.zoneland.knowledge.event;

import java.util.Date;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.dao.QaRecordsV2Mapper;
import net.zoneland.knowledge.enums.QueStyleEnum;
import net.zoneland.knowledge.enums.QueryTypeEnum;
import net.zoneland.knowledge.model.EsQuestion;
import net.zoneland.knowledge.model.LoginUserPojo;
import net.zoneland.knowledge.model.QaQueryDto;
import net.zoneland.knowledge.model.QaRecordsV2;
import net.zoneland.knowledge.model.QaResponse;
import net.zoneland.knowledge.service.impl.search.SearchDto;
import net.zoneland.knowledge.utils.GsonUtils;

/**
 * .
 *
 * @author: bcc
 * 2021/6/3
 */
@Component
public class QaRecordEventListener implements DisposableBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(QaRecordEventListener.class);

    @Autowired
    private QaRecordsV2Mapper qaRecordsV2Mapper;

    /**
     * 线程池，事件总线异步执行，尽量不影响查询速度
     */
    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1,
            1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque(),
            new ThreadFactoryBuilder().setNameFormat("QaRecordEventListener-pool-%d").build()
    );

    @Subscribe
    @AllowConcurrentEvents
    public void listenSearchDto(final SearchDto searchDto) {
        poolExecutor.execute(() -> {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("entry listenSearchDto");
            }
            QaQueryDto qaQueryDto = searchDto.getQaQueryDto();
            //板块切换不保存到我的足迹
            if (qaQueryDto.isSwitchCategory()) {
                LOGGER.debug("当前查询分类：{}, 板块切换不保存到我的足迹！", 
                             qaQueryDto.getCategoryList().stream().collect(Collectors.joining(Constants.STRING_SEMICOLON)));
                return;
            }
            final QaResponse qaResponse = searchDto.getQaResponse();
            final LoginUserPojo loginUserPojo = qaQueryDto.getLoginUserPojo();
            final QaRecordsV2 qaRecordsV2 = new QaRecordsV2(loginUserPojo);
            qaRecordsV2.setId(searchDto.getAnswerId());
            qaRecordsV2.setSessionId(qaQueryDto.getTalkSessionId());
            qaRecordsV2.setPraise(-1);
            qaRecordsV2.setQueStyle(QueStyleEnum.PROFESSION_TALK.getValue());
            qaRecordsV2.setQueryText(qaQueryDto.getQueryText());

            qaRecordsV2.setAnsCode(1);
            final String ansContent = GsonUtils.GSON.toJson(qaResponse);
            qaRecordsV2.setAnsContent(ansContent);
            if (ansContent.contains("十分抱歉")){
                qaRecordsV2.setHasAnswer(false);
            }
            if (null == searchDto.getEsQuestions()) {
                qaRecordsV2.setFinalAnswer(1);
            } else if (searchDto.getEsQuestions().size() == 1) {
                qaRecordsV2.setFinalAnswer(1);
                EsQuestion esQuestion = searchDto.getEsQuestions().get(0);
                qaRecordsV2.setBankId(esQuestion.getId());
            } else {
                qaRecordsV2.setFinalAnswer(0);
            }
            qaRecordsV2.setQaType(qaQueryDto.getQaType().getValue());
            if (QueryTypeEnum.QUERY_BY_ID == qaQueryDto.getQaType()) {
                if (null != searchDto.getEsQuestions()) {
                    EsQuestion esQuestion = searchDto.getEsQuestions().get(0);
                    qaRecordsV2.setCategory(Constants.STRING_SPLIT + esQuestion.getCategory() + Constants.STRING_SPLIT);
                    qaRecordsV2.setLevel1Title(esQuestion.getLevel1Title());
                    qaRecordsV2.setLevel2Title(esQuestion.getLevel2Title());
                    qaRecordsV2.setLevel3Title(esQuestion.getLevel3Title());
                    qaRecordsV2.setLevel4Title(esQuestion.getQuestion());
                    //查询问题 将最后一级作为问题
                    String queryText = qaRecordsV2.getLevel1Title();
                    if (StringUtils.isNotBlank(qaRecordsV2.getLevel2Title())) {
                        queryText = qaRecordsV2.getLevel2Title();
                    }
                    if (StringUtils.isNotBlank(qaRecordsV2.getLevel3Title())) {
                        queryText = qaRecordsV2.getLevel3Title();
                    }
                    qaRecordsV2.setQueryText(queryText);
                }
            } else if (QueryTypeEnum.QUERY_BY_PATH == qaQueryDto.getQaType()) {
                qaRecordsV2.setLevel1Title(qaQueryDto.getLevel1Title());
                qaRecordsV2.setLevel2Title(qaQueryDto.getLevel2Title());
                qaRecordsV2.setLevel3Title(qaQueryDto.getLevel3Title());
                qaRecordsV2.setCategory(Constants.STRING_SPLIT + qaQueryDto.getCategory() + Constants.STRING_SPLIT);
                //查询问题 将最后一级作为问题
                String queryText = qaRecordsV2.getLevel1Title();
                if(StringUtils.isNotBlank(qaRecordsV2.getLevel2Title())) {
                    queryText = qaRecordsV2.getLevel2Title();
                }
                if(StringUtils.isNotBlank(qaRecordsV2.getLevel3Title())) {
                    queryText = qaRecordsV2.getLevel3Title();
                }
                if(StringUtils.isNotBlank(qaRecordsV2.getLevel4Title())) {
                    queryText = qaRecordsV2.getLevel4Title();
                }
                qaRecordsV2.setQueryText(queryText);
            } else if (QueryTypeEnum.SEARCH == qaQueryDto.getQaType()) {
                qaRecordsV2.setCategory(Constants.STRING_SPLIT
                    + qaQueryDto.getCategoryList().stream().collect(Collectors.joining(Constants.STRING_SPLIT))
                    + Constants.STRING_SPLIT);
                if (StringUtils.isNotBlank(qaQueryDto.getQueryLevel1Title())) {
                    qaRecordsV2.setLevel1Title(qaQueryDto.getQueryLevel1Title());
                } else {
                    qaRecordsV2.setLevel1Title(searchDto.getLeve1Title());
                }
            }
            qaRecordsV2.setClickSearch(qaQueryDto.getClickSearch());
            qaRecordsV2.setCreateTime(new Date());
            qaRecordsV2.setVisitType(qaQueryDto.getVisitType());
            qaRecordsV2Mapper.insert(qaRecordsV2);
        });
    }

    @Override
    public void destroy() throws Exception {
        poolExecutor.shutdown();
    }
}
